package ru.incoremedia.gwttest.application.client.view.user.notesgroup;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.ArrayList;
import java.util.List;
import ru.incoremedia.gwttest.application.client.i18n.I18N;
import ru.incoremedia.gwttest.application.client.view.user.noteitem.DragZone;
import ru.incoremedia.gwttest.application.client.view.user.noteitem.NoteItem;
import ru.incoremedia.gwttest.application.client.view.user.notespage.NotesPage;
import ru.incoremedia.gwttest.core.client.component.autosizedtextarea.TextChangeHandler;


public class NotesGroup extends Composite {

    public interface Styles extends CssResource {
        String newNotesGroup();
        String moveCursor();
        String defaultCursor();
        String target();
        String notesGroupDivCollapsed();
        String deleteNotesGroup();
        String deleteButtonLight();
        String deleteControlZone();
    }

    @UiField Styles style;

    private boolean isNew = false;

    private boolean isDelete = false;

    interface MyUiBinder extends UiBinder<Widget, NotesGroup> {}

    private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

    @UiField FlowPanel notesContainer;

    @UiField GroupNameTextBox groupNameTextBox;

    @UiField DragZone dragZone;

    @UiField SimplePanel controlZone;

    @UiField Button deleteButton;

    private NotesPage notesPage;

    public NotesGroup(final NotesPage notesPage) {
        this.notesPage = notesPage;
        initWidget(uiBinder.createAndBindUi(this));
        setNew(true);

        groupNameTextBox.addFocusHandler(new FocusHandler() {
            @Override
            public void onFocus(FocusEvent event) {
                if(isNew()) {
                    groupNameTextBox.setText("");
                }
            }
        });

        groupNameTextBox.addBlurHandler(new BlurHandler() {
            @Override
            public void onBlur(BlurEvent event) {
                if(isNew()) {
                    setNew(true);
                }
            }
        });

        deleteButton.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                if(!isNew) {
                    if(!isDelete) {
                        setDelete(true);
                    } else {
                        setDelete(false);
                    }
                }
            }
        });
    }

    public List<NoteItem> getNoteItems() {
        List<NoteItem> noteItems = new ArrayList<NoteItem>();

        for(int i = 0; i < notesContainer.getWidgetCount(); i++) {
            Widget widget = notesContainer.getWidget(i);
            if(widget instanceof NoteItem) {
                noteItems.add((NoteItem)widget);
            }
        }

        return noteItems;
    }

    public void setDelete(boolean isDelete) {
        this.isDelete = isDelete;
        if(isDelete) {
            groupNameTextBox.addStyleName(style.deleteNotesGroup());
            deleteButton.addStyleName(style.deleteButtonLight());
            controlZone.addStyleName(style.deleteControlZone());
            groupNameTextBox.setReadOnly(true);            

            for(NoteItem noteItem : getNoteItems()) {
                noteItem.setVisible(false);
            }

            isDelete = true;
        } else {
            groupNameTextBox.removeStyleName(style.deleteNotesGroup());
            deleteButton.removeStyleName(style.deleteButtonLight());
            controlZone.removeStyleName(style.deleteControlZone());
            groupNameTextBox.setReadOnly(false);            

            for(NoteItem noteItem : getNoteItems()) {
                noteItem.setVisible(true);
            }

            isDelete = false;
        }
    }

    public void addNewNote() {
        final NoteItem note = new NoteItem(this);

        note.getTextArea().addTextChangeHandler(new TextChangeHandler() {
            @Override
            public void onChange() {
                if(note.getTextArea().getText().length() > 0 && note.isNew()) {
                    addNewNote();
                    note.setNew(false);
                }
            }
        });

        note.getDragZone().addMouseDownHandler(new MouseDownHandler() {
            @Override
            public void onMouseDown(final MouseDownEvent event) {
                event.preventDefault();
                notesPage.startDraggingNoteItem(note, event.getNativeEvent());
            }
        });

        note.getDragZone().addMouseOverHandler(new MouseOverHandler() {
            @Override
            public void onMouseOver(MouseOverEvent event) {
                notesPage.selectTargetNoteItem(note);
            }
        });

        note.getTextArea().addMouseOverHandler(new MouseOverHandler() {
            @Override
            public void onMouseOver(MouseOverEvent event) {
                notesPage.selectTargetNoteItem(note);
            }
        });

        notesContainer.add(note);
        notesPage.correctTabOrders();
    }

    public void setNew(boolean isNew) {
        this.isNew = isNew;
        if(isNew) {
            groupNameTextBox.setText(I18N.constants.newGroupText());
            groupNameTextBox.addStyleName(style.newNotesGroup());
            controlZone.addStyleName(style.newNotesGroup());
        } else {
            groupNameTextBox.removeStyleName(style.newNotesGroup());
            controlZone.removeStyleName(style.newNotesGroup());
        }
    }

    public boolean isNew() {
        return isNew;
    }

    public GroupNameTextBox getGroupNameTextBox() {
        return groupNameTextBox;
    }

    public FlowPanel getNotesContainer() {
        return notesContainer;
    }

    public DragZone getDragZone() {
        return dragZone;
    }

    public void disableTargetStyle() {
        groupNameTextBox.removeStyleName(style.target());
        controlZone.removeStyleName(style.target());
    }

    public void enableTargetStyle() {
        groupNameTextBox.addStyleName(style.target());
        controlZone.addStyleName(style.target());
    }

    public void enableItemMoveStyle() {
        groupNameTextBox.addStyleName(style.defaultCursor());
        dragZone.removeStyleName(style.moveCursor());
        groupNameTextBox.setFocus(false);
    }

    public void disableItemMoveStyle() {
        groupNameTextBox.removeStyleName(style.defaultCursor());
        dragZone.addStyleName(style.moveCursor());
    }

    public void enableGroupMoveStyle() {
        groupNameTextBox.addStyleName(style.defaultCursor());
        notesContainer.addStyleName(style.notesGroupDivCollapsed());
        dragZone.removeStyleName(style.moveCursor());
        groupNameTextBox.setFocus(false);
    }

    public void disableGroupMoveStyle() {
        groupNameTextBox.removeStyleName(style.defaultCursor());
        notesContainer.removeStyleName(style.notesGroupDivCollapsed());
        dragZone.addStyleName(style.moveCursor());
    }

    public NotesPage getNotesPage() {
        return notesPage;
    }

    public void setNotesPage(NotesPage notesPage) {
        this.notesPage = notesPage;
    }

    public boolean isDelete() {
        return isDelete;
    }
}
